import Shader3D = Laya.Shader3D;
import SubShader = Laya.SubShader;
import BaseTexture = Laya.BaseTexture;
import ShaderPass = Laya.ShaderPass;
import VertexMesh = Laya.VertexMesh;
import Material = Laya.Material;
import RenderState = Laya.RenderState;

import MYShaderVS from "./MYShader.vs";
import MYShaderPS from "./MYShader.fs";
export default class MYShaderMaterial extends Laya.Material {
    public static ALBEDOTEXTURE: number = Shader3D.propertyNameToID("u_DiffuseTexture");
    public static NOISE_TEX: number = Shader3D.propertyNameToID("u_NoiseTex");

    public static CULL: number = Shader3D.propertyNameToID("s_Cull");
    public static BLEND: number = Shader3D.propertyNameToID("s_Blend");
    public static BLEND_SRC: number = Shader3D.propertyNameToID("s_BlendSrc");
    public static BLEND_DST: number = Shader3D.propertyNameToID("s_BlendDst");
    public static DEPTH_TEST: number = Shader3D.propertyNameToID("s_DepthTest");
    public static DEPTH_WRITE: number = Shader3D.propertyNameToID("s_DepthWrite");
    public static MATERIALSPECULAR: number = Shader3D.propertyNameToID("u_MaterialSpecular");
	public static SHININESS: number = Shader3D.propertyNameToID("u_Shininess");
	public static WATER_SCALE: number = Shader3D.propertyNameToID("u_WaterScale");
	
    constructor() {
        super();
        this.setShaderName("MYShaderMaterial");

        // case BlinnPhongMaterial.RENDERMODE_OPAQUE:
            // this.alphaTest = false;
            // this.renderQueue = Material.RENDERQUEUE_OPAQUE;
            // this.depthWrite = true;
            // this.cull = RenderState.CULL_BACK;
            // this.blend = RenderState.BLEND_DISABLE;
            // this.depthTest = RenderState.DEPTHTEST_LESS;
            // break;
        // case BlinnPhongMaterial.RENDERMODE_CUTOUT:
        //     this.renderQueue = Material.RENDERQUEUE_ALPHATEST;
        //     this.alphaTest = true;
        //     this.depthWrite = true;
        //     this.cull = RenderState.CULL_BACK;
        //     this.blend = RenderState.BLEND_DISABLE;
        //     this.depthTest = RenderState.DEPTHTEST_LESS;
        //     break;
        // case BlinnPhongMaterial.RENDERMODE_TRANSPARENT:
        //     this.renderQueue = Material.RENDERQUEUE_TRANSPARENT;
        //     this.alphaTest = false;
        //     this.depthWrite = false;
        //     this.cull = RenderState.CULL_BACK;
        //     this.blend = RenderState.BLEND_ENABLE_ALL;
        //     this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA;
        //     this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA;
        //     this.depthTest = RenderState.DEPTHTEST_LESS;

        // case BlinnPhongMaterial.RENDERMODE_TRANSPARENT:
        // 透明混合的渲染队列设置
        this.renderQueue = Laya.BaseMaterial.RENDERQUEUE_TRANSPARENT;
        this.alphaTest = false;
        this._shaderValues.setBool(MYShaderMaterial.DEPTH_WRITE, true);
        this._shaderValues.setInt(MYShaderMaterial.CULL, Laya.RenderState.CULL_BACK);
        this._shaderValues.setInt(MYShaderMaterial.BLEND, Laya.RenderState.BLEND_ENABLE_ALL);
        this._shaderValues.setInt(MYShaderMaterial.BLEND_SRC, Laya.RenderState.BLENDPARAM_SRC_ALPHA);
        this._shaderValues.setInt(MYShaderMaterial.BLEND_DST, Laya.RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA);
        this._shaderValues.setInt(MYShaderMaterial.DEPTH_TEST, Laya.RenderState.DEPTHTEST_LESS);
    }

    public static initShader() {
        // 直接粘贴过来的，不知道laya有哪些内置变量，多余没用的先放着，用的时候好查。
        //BLINNPHONG
        var attributeMap: any = {
            'a_Position': VertexMesh.MESH_POSITION0,
            'a_Color': VertexMesh.MESH_COLOR0,
            'a_Normal': VertexMesh.MESH_NORMAL0,
            'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0,
            'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1,
            'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0,
            'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0,
            'a_Tangent0': VertexMesh.MESH_TANGENT0,
            'a_MvpMatrix': VertexMesh.MESH_MVPMATRIX_ROW0,
            'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0
        };
        var uniformMap: any = {
            'u_Bones': Shader3D.PERIOD_CUSTOM,
            'u_DiffuseTexture': Shader3D.PERIOD_MATERIAL,
            'u_NoiseTex': Shader3D.PERIOD_MATERIAL,
            'u_SpecularTexture': Shader3D.PERIOD_MATERIAL,
            'u_NormalTexture': Shader3D.PERIOD_MATERIAL,
            'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL,
            'u_DiffuseColor': Shader3D.PERIOD_MATERIAL,
            'u_MaterialSpecular': Shader3D.PERIOD_MATERIAL,
            'u_Shininess': Shader3D.PERIOD_MATERIAL,
            'u_WaterScale': Shader3D.PERIOD_MATERIAL,
            'u_TilingOffset': Shader3D.PERIOD_MATERIAL,

            'u_WorldMat': Shader3D.PERIOD_SPRITE,
            'u_MvpMatrix': Shader3D.PERIOD_SPRITE,
            'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE,
            'u_LightMap': Shader3D.PERIOD_SPRITE,
            'u_LightMapDirection': Shader3D.PERIOD_SPRITE,

            'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE,
            'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE,
            'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE,

            'u_CameraPos': Shader3D.PERIOD_CAMERA,
            'u_Viewport': Shader3D.PERIOD_CAMERA,
            'u_ProjectionParams': Shader3D.PERIOD_CAMERA,
            'u_View': Shader3D.PERIOD_CAMERA,
            'u_ViewProjection': Shader3D.PERIOD_CAMERA,

            'u_ReflectTexture': Shader3D.PERIOD_SCENE,
            'u_ReflectIntensity': Shader3D.PERIOD_SCENE,
            'u_FogStart': Shader3D.PERIOD_SCENE,
            'u_FogRange': Shader3D.PERIOD_SCENE,
            'u_FogColor': Shader3D.PERIOD_SCENE,
            'u_DirationLightCount': Shader3D.PERIOD_SCENE,
            'u_LightBuffer': Shader3D.PERIOD_SCENE,
            'u_LightClusterBuffer': Shader3D.PERIOD_SCENE,
            'u_AmbientColor': Shader3D.PERIOD_SCENE,
            'u_ShadowBias': Shader3D.PERIOD_SCENE,
            'u_ShadowLightDirection': Shader3D.PERIOD_SCENE,
            'u_ShadowMap': Shader3D.PERIOD_SCENE,
            'u_ShadowParams': Shader3D.PERIOD_SCENE,
            'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE,
            'u_ShadowMatrices': Shader3D.PERIOD_SCENE,
            'u_ShadowMapSize': Shader3D.PERIOD_SCENE,
            'u_SpotShadowMap': Shader3D.PERIOD_SCENE,
            'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE,
            'u_ShadowLightPosition': Shader3D.PERIOD_SCENE,

            //GI
            'u_AmbientSHAr': Shader3D.PERIOD_SCENE,
            'u_AmbientSHAg': Shader3D.PERIOD_SCENE,
            'u_AmbientSHAb': Shader3D.PERIOD_SCENE,
            'u_AmbientSHBr': Shader3D.PERIOD_SCENE,
            'u_AmbientSHBg': Shader3D.PERIOD_SCENE,
            'u_AmbientSHBb': Shader3D.PERIOD_SCENE,
            'u_AmbientSHC': Shader3D.PERIOD_SCENE,


            //legacy lighting
            'u_DirectionLight.color': Shader3D.PERIOD_SCENE,
            'u_DirectionLight.direction': Shader3D.PERIOD_SCENE,
            'u_PointLight.position': Shader3D.PERIOD_SCENE,
            'u_PointLight.range': Shader3D.PERIOD_SCENE,
            'u_PointLight.color': Shader3D.PERIOD_SCENE,
            'u_SpotLight.position': Shader3D.PERIOD_SCENE,
            'u_SpotLight.direction': Shader3D.PERIOD_SCENE,
            'u_SpotLight.range': Shader3D.PERIOD_SCENE,
            'u_SpotLight.spot': Shader3D.PERIOD_SCENE,
            'u_SpotLight.color': Shader3D.PERIOD_SCENE,
            
            'u_Time': Shader3D.PERIOD_SCENE,
        };
        var stateMap: any = {
            's_Cull': Shader3D.RENDER_STATE_CULL,
            's_Blend': Shader3D.RENDER_STATE_BLEND,
            's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC,
            's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST,
            's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST,
            's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE
        }
        var shader: Shader3D = Shader3D.add("MYShaderMaterial", null, null, true);
        var subShader: SubShader = new SubShader(attributeMap, uniformMap);
        shader.addSubShader(subShader);
        subShader.addShaderPass(MYShaderVS, MYShaderPS, stateMap);
    }

    static SHADERDEFINE_DIFFUSEMAP: Laya.ShaderDefine;
    set albedoTexture(value: BaseTexture) {
        this._shaderValues.setTexture(MYShaderMaterial.ALBEDOTEXTURE, value);
    }
    set noiseTex(value: BaseTexture) {
        this._shaderValues.setTexture(MYShaderMaterial.NOISE_TEX, value);
    }
    get _SpecColor(): Laya.Vector4 {
		return this._shaderValues.getVector(MYShaderMaterial.MATERIALSPECULAR);
	}

	get specularColor(): Laya.Vector4 {
		return (<Laya.Vector4>this._shaderValues.getVector(MYShaderMaterial.MATERIALSPECULAR));
	}

	set specularColor(value: Laya.Vector4) {
		this._shaderValues.setVector(MYShaderMaterial.MATERIALSPECULAR, value);
	}
	set _SpecColor(value: Laya.Vector4) {
		this.specularColor = value;
    }
	get _Shininess(): number {
		return this._shaderValues.getNumber(MYShaderMaterial.SHININESS);
	}

	set _Shininess(value: number) {
		value = Math.max(0.0, Math.min(1.0, value));
		this._shaderValues.setNumber(MYShaderMaterial.SHININESS, value);
	}
 
	get shininess(): number {
		return this._Shininess;
	}

	set shininess(value: number) {
		this._Shininess = value;
    }
    
    set waterScale(value: number) {
		this._shaderValues.setNumber(MYShaderMaterial.WATER_SCALE, value);
    }
}